package com.ctshk.rpc.order.goods.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ctshk.common.dto.Result;
import com.ctshk.common.enums.*;
import com.ctshk.common.exception.BusinessException;
import com.ctshk.common.vo.OrderRefundDTO;
import com.ctshk.rpc.finance.json.AccountJson;
import com.ctshk.rpc.finance.req.bill.BillAddRefundReq;
import com.ctshk.rpc.finance.service.IFinanceBillService;
import com.ctshk.rpc.order.goods.entity.*;
import com.ctshk.rpc.order.goods.mapper.*;
import com.ctshk.rpc.order.goods.req.CommodityOrderRefundReq;
import com.ctshk.rpc.order.goods.req.OrderRefundApprovalRecordReq;
import com.ctshk.rpc.order.goods.req.OrderRefundApprovalReq;
import com.ctshk.rpc.order.goods.service.IOrderCommodityRefundService;
import com.ctshk.rpc.system.dto.SysDepartmentDTO;
import com.ctshk.rpc.system.dto.UserDTO;
import com.ctshk.rpc.system.service.ISysDepartmentService;
import com.ctshk.rpc.system.service.ISysUserService;
import com.ctshk.rpc.workflow.dto.ApprovalCheckDTO;
import com.ctshk.rpc.workflow.service.ISysApprovalService;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 商品退款记录 服务实现类
 * </p>
 *
 * @author 姜斌文
 * @since 2021-04-19
 */
@Slf4j
@DubboService
public class OrderCommodityRefundServiceImpl extends ServiceImpl<OrderCommodityRefundMapper, OrderCommodityRefund> implements IOrderCommodityRefundService {


    @Autowired
    private OrderCommodityRefundMapper orderCommodityRefundMapper;

    @Autowired
    private OrderConsigneeInfoMapper orderConsigneeInfoMapper;

    @Autowired
    private OrderShipperInfoMapper orderShipperInfoMapper;

    @DubboReference
    private ISysUserService sysUserService;

    @DubboReference
    private IFinanceBillService financeBillService;

    @Autowired
    private OrderCommodityMapper orderCommodityMapper;
    @Autowired
    private OrderShipperInfoMapper shipperInfoMapper;

    @DubboReference
    private ISysDepartmentService sysDepartmentService;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private CommodityMapper commodityMapper;

    @DubboReference
    private ISysApprovalService sysApprovalService;

    @Override
    public Result<List<OrderRefundDTO>> refundList(CommodityOrderRefundReq req) {
//        Page<CommodityOrderRefundListDTO> iPage = new Page<>(req.getPageNo(),req.getPageSize());
        // 根据条件查询商品订单退款记录明细
        List<OrderCommodityRefund> page = orderCommodityRefundMapper.queryRefundListByCondition(req);
        if (CollectionUtils.isEmpty(page)) {
            return Result.success(null);
        }
//        page.stream().forEach(dto -> {
//            if (dto.getSaleUserId() != null){
//                // 获取销售对象
//                UserDTO userDTO = sysUserService.queryCacheUser(dto.getSaleUserId());
//                if (null != userDTO){
//                    dto.setSaleUserDept(userDTO.getDept());
//                }
//            }
//            if (StringUtils.isNotBlank(dto.getRefundAccountJson())){
//                // 退款账户JSON
//                AccountJson accountJson = JSON.parseObject(dto.getRefundAccountJson(),AccountJson.class);
//                dto.setAccountJson(accountJson);
//            }
//        });
        List<OrderRefundDTO> orderRefundDTOS = new ArrayList<>();
        for (OrderCommodityRefund orderRefundListDTO : page) {
            OrderRefundDTO orderRefundDTO = new OrderRefundDTO();
            orderRefundDTO.setId(orderRefundListDTO.getId()); // ID
//            orderRefundDTO.setRefundId(); // 退款id
            orderRefundDTO.setBusinessType(SystemBusinessType.COMMODITY.getCode()); // 业务类型
            orderRefundDTO.setRefundType(orderRefundListDTO.getRefundWay()); // 退款方式
            orderRefundDTO.setRefundNumber(orderRefundListDTO.getRefundNumber()); // 退款单号
            orderRefundDTO.setTouristName(""); // 旅客名称
            orderRefundDTO.setRefundAccount(orderRefundDTO.getRefundAccount()); // 退款账户
            orderRefundDTO.setTotalReceivables(orderRefundListDTO.getRefundAmount()); // 应收金额
            orderRefundDTO.setPaidInAmount(orderRefundListDTO.getRefundAmount()); // 实收金额
            orderRefundDTO.setRefundAmount(orderRefundListDTO.getRefundAmount()); // 退款金额
//            orderRefundDTO.setRefundDetail(); // 退款明细
            orderRefundDTO.setCurrency(orderRefundListDTO.getCurrency()); // 币种
            orderRefundDTO.setRefundReason(orderRefundListDTO.getRefundReason()); // 退款原因
            orderRefundDTO.setRemark(orderRefundListDTO.getRemark()); // 备注
            orderRefundDTO.setApprovalAmount(orderRefundListDTO.getRefundAmount()); // 允许退款金额
            orderRefundDTOS.add(orderRefundDTO);
        }
//        PageResponse<CommodityOrderRefundListDTO> response = new PageResponse<CommodityOrderRefundListDTO>(
//                page.getRecords(),
//                page.getCurrent() == 1,
//                page.getTotal() <= (page.getCurrent() * page.getSize()),
//                page.getTotal(),
//                page.getCurrent(),
//                page.getSize());
        return Result.success(orderRefundDTOS);
    }

    /**
     * 商品订单--退款审批
     *
     * @param req
     * @return
     */
    @Override
    public Result approval(OrderRefundApprovalReq req) {
        log.info("【中旅商城--退款审批--start】，入参为:{}", JSON.toJSONString(req));
        // 审批实例id不能为空
        if (null == req.getApprovalId()) {
            return Result.failed(SystemError.SYS_402);
        }
        // 审批状态判断
        if (!ApprovalStatus.isCheckStatus(req.getApprovalStatus())) {
            return Result.failed(SystemError.SYS_402);
        }
        Order order = orderMapper.selectOrderById(req.getOrderId());
        log.info("【中旅商城--退款审批--查询订单】，返参为：{}", JSON.toJSONString(order));
        if (null == order) {
            return Result.failed(SystemError.MALL_MERCHANDISE_23033);
        }
        if (!ApprovalStatus.REVIEWING.getCode().equals(order.getCancelStatus())) {
            return Result.failed(SystemError.MALL_MERCHANDISE_23042);
        }
        List<OrderCommodityRefund> orderCommodityRefundList = orderCommodityRefundMapper.selectListByOrderId(req.getOrderId());
        log.info("【中旅商城--退款审批--查询商品退款记录】，返参为:{}", JSON.toJSONString(orderCommodityRefundList));
        if (CollectionUtils.isEmpty(orderCommodityRefundList)) {
            return Result.failed(SystemError.MALL_MERCHANDISE_23043);
        }
        LocalDateTime now = LocalDateTime.now();
        log.info("【中旅商城--退款审批--approval状态】，入参为：{}", req.getApprovalStatus());
        if (ApprovalStatus.REVIEW_YES.getCode() == req.getApprovalStatus()) {
            if (CollectionUtils.isEmpty(req.getOrderCommodityRefundReqList())) {
                throw new BusinessException(SystemError.MALL_MERCHANDISE_23044);
            }
            // 审批通过
            order.setCancelStatus(ApprovalStatus.REVIEW_YES.getCode());
            // 校验审批金额
            BigDecimal totalAmount = BigDecimal.ZERO;
            for (OrderCommodityRefund orderCommodityRefund : orderCommodityRefundList) {
                // 审批状态设置
                orderCommodityRefund.setStatus(ApprovalStatus.REVIEW_YES.getCode());
                for (OrderRefundApprovalRecordReq commodityRefundReq : req.getOrderCommodityRefundReqList()) {
                    if (Objects.equals(commodityRefundReq.getId(), orderCommodityRefund.getId())) {
                        // 审批退款金额获取
                        BigDecimal approvalAmount = commodityRefundReq.getApprovalAmount();
                        // 退款金额设置
                        totalAmount = totalAmount.add(approvalAmount.multiply(new BigDecimal(orderCommodityRefund.getExchangeRate())));
                        orderCommodityRefund.setRefundAmount(commodityRefundReq.getApprovalAmount());
                        break;
                    }
                }
            }



            log.info("【中旅商城--退款审批--查询商品订单】，入参为：{}", order.getId());
            List<OrderCommodity> orderCommodities = orderCommodityMapper.selectListByOrderId(order.getId());
            log.info("【中旅商城--退款审批--查询商品订单】，返回结果为：{}", JSON.toJSONString(orderCommodities));
            if (CollectionUtils.isEmpty(orderCommodities)) {
                throw new BusinessException(SystemError.MALL_MERCHANDISE_23033);
            }

            // 退改手续费用获取
//            BigDecimal refundAmount = new BigDecimal("0");
//            for (OrderCommodity orderCommodity : orderCommodities) {
//                Commodity commodity = commodityMapper.selectCommodityById(orderCommodity.getCommodityId().toString());
//                BigDecimal cancellationCharge = getCancellationCharge(commodity, orderCommodity);
//                refundAmount = order.getOrderAmount().subtract(cancellationCharge);
//                if (totalAmount.compareTo(refundAmount) > 0) {
//                    throw new BusinessException(SystemError.AIREXPRESS_ORDER_60035);
//                }
//            }

            /**
             * 退款确认--新增退款记录
             */
            UserDTO userSaleDTO = sysUserService.queryCacheUser(order.getSaleUserId());
            List<BillAddRefundReq> billAddRefundReqs = new ArrayList<>();
            for (OrderCommodityRefund orderCommodityRefund : orderCommodityRefundList) {
                List<Long> productId = new ArrayList<>();
                List<String> resourceInfo = new ArrayList<>();
                BillAddRefundReq billAddRefundReq = new BillAddRefundReq();
                billAddRefundReq.setBillNumber(orderCommodityRefund.getRefundNumber()); // 退款单号
                billAddRefundReq.setBusinessType(SystemBusinessType.COMMODITY.getCode()); // 业务类型
                billAddRefundReq.setCollectionAmount(orderCommodityRefund.getRefundAmount()); // 退款金额
                billAddRefundReq.setCurrencyId(orderCommodityRefund.getCurrencyId()); // 币种id
                billAddRefundReq.setCurrencyName(orderCommodityRefund.getCurrency()); // 币种名称
                billAddRefundReq.setExchangeRate(orderCommodityRefund.getExchangeRate()); // 汇率
                billAddRefundReq.setSaleOrderNumber(order.getOrderNumber()); // 销售单号
                billAddRefundReq.setSaleOrderId(order.getId()); // 销售id
                for (OrderCommodity orderCommodity : orderCommodities) {
                    productId.add(orderCommodity.getCommodityId());
                    resourceInfo.add(orderCommodity.getCommodityName());
                }
                billAddRefundReq.setProductId(productId); // 产品id
                billAddRefundReq.setResourceInfo(resourceInfo); // 资源信息列表
//                billAddRefundReq.setProductNumber(orderCommodities.get(0).getCommodityNumber()); // 产品编号
//                billAddRefundReq.setProductName(orderCommodities.get(0).getCommodityName()); // 产品名称
                billAddRefundReq.setSaleUserId(userSaleDTO.getId()); // 销售人id
                billAddRefundReq.setSaleUserName(userSaleDTO.getFullName()); // 销售人名称
                //部门代码
                SysDepartmentDTO sysDepartmentDTO = sysDepartmentService.queryByUserId(userSaleDTO.getId());
                if (null != sysDepartmentDTO) {
                    billAddRefundReq.setSaleDeptId(sysDepartmentDTO.getId()); // 销售部门id
                }
                billAddRefundReq.setRefundTypeId(orderCommodityRefund.getRefundWayId()); // 退款方式id
                billAddRefundReq.setRefundType(orderCommodityRefund.getRefundWay()); // 退款方式
                AccountJson refundAccountJson = new AccountJson();
                refundAccountJson.setCardNumber(orderCommodityRefund.getRefundAccount()); // 卡号
//                refundAccountJson.setBankName(""); // 银行名称
//                refundAccountJson.setBankAddress(""); // 银行地址

                billAddRefundReq.setRefundAccountJson(refundAccountJson); // 退款账户JSON
                billAddRefundReq.setTouristSource(order.getOrderSourceType()); // 旅客来源1 散客 2 大客户 3 代理商
                if (order.getOrderSourceType().intValue() == 2) {  // 大客户
                    billAddRefundReq.setBigClientId(order.getBigClientId()); // 大客户ID
                    billAddRefundReq.setBigClientName(order.getBigClientName()); // 大客户名称
                }
                if (order.getDeliveryMode().intValue() == 1) { // 物流配送
                    OrderConsigneeInfo consigneeInfoByOrder = orderConsigneeInfoMapper.findConsigneeInfoByOrder(order.getId());
                    if (null == consigneeInfoByOrder) {
                        throw new BusinessException(SystemError.GOODS_ORDER_ERROR_40008);
                    }
                    billAddRefundReq.setTouristName(consigneeInfoByOrder.getConsignee()); // 旅客姓名
                    billAddRefundReq.setContactMobile(consigneeInfoByOrder.getConsigneePhone()); // 联系电话
                } else if (order.getDeliveryMode().intValue() == 2) { // 门店自提
                    OrderShipperInfo shipperInfo = orderShipperInfoMapper.findInfoByOrderId(order.getId());
                    if (null == shipperInfo) {
                        throw new BusinessException(SystemError.GOODS_ORDER_ERROR_40008);
                    }
                    billAddRefundReq.setTouristName(shipperInfo.getShipper()); // 旅客姓名
                    billAddRefundReq.setContactMobile(shipperInfo.getShipperPhone()); // 联系电话
                }
                billAddRefundReq.setRefundTime(LocalDateTime.now()); // 退款时间
                billAddRefundReq.setPayVoucherJson(Lists.newArrayList()); // 付款凭证
                billAddRefundReq.setRefundRemark(orderCommodityRefund.getRemark()); // 退款备注
                billAddRefundReq.setUserId(userSaleDTO.getId()); // 用户id
                billAddRefundReqs.add(billAddRefundReq);
            }
            log.info("【中旅商城B端--退款审批--新增退款记录】，入参为:{}", JSON.toJSONString(billAddRefundReqs));
            financeBillService.addRefund(billAddRefundReqs);
            log.info("【中旅商城B端--退款审批--确认退款更新状态--end】");

        }else if(ApprovalStatus.REVIEW_NO.getCode() == req.getApprovalStatus()){
            // 审批不通过
            order.setCancelStatus(ApprovalStatus.REVIEW_NO.getCode());
            for (OrderCommodityRefund orderCommodityRefund : orderCommodityRefundList) {
                orderCommodityRefund.setStatus(ApprovalStatus.REVIEW_NO.getCode());
            }
        }else {
            // 撤回
            order.setCancelStatus(null);
            for (OrderCommodityRefund orderCommodityRefund : orderCommodityRefundList) {
                orderCommodityRefund.setStatus(null);
                orderCommodityRefund.setIsDeleted(IsDeletedCode.YES.getCode());
            }
        }

        /**
         * 发起审批
         */
        Result<ApprovalCheckDTO> check = sysApprovalService.check(req.getApprovalId(), req.getUserId(), req.getApprovalStatus(), req.getComments());
        if (!check.isSuccess()){
            SystemError systemError = SystemError.getDefined(check.getCode());
            return Result.failed(systemError);
        }
        if (check.getData() == null || !check.getData().getIsFinish()){
            return Result.success();
        }
        for (OrderCommodityRefund orderCommodityRefund : orderCommodityRefundList) {
            orderCommodityRefund.setModifiedId(req.getUserId());
            orderCommodityRefund.setGmtModified(now);
            orderCommodityRefundMapper.updateById(orderCommodityRefund);
        }
        order.setModifiedId(req.getUserId());
        order.setGmtModified(now);
        orderMapper.updateOrderById(order);
        log.info("【中旅商城--退款审批--end】");
        return Result.success();
    }

    @Autowired
    CommodityCostMapper costMapper;

    /**
     * 获取退改手续费
     * @param commodity
     * @return
     */
    private BigDecimal getCancellationCharge(Commodity commodity,OrderCommodity orderCommodity){
//        if (Arrays.asList(1,2).contains(commodity.getRefundServiceChargeType())){
            // 订单商品设置退改手续费
            if (Objects.equals(commodity.getRefundServiceChargeType(), ServiceChargeType.PERCENTAGE.getCode())){
                BigDecimal percentage = commodity.getRefundServiceCharge().divide(new BigDecimal("100"));
                return orderCommodity.getCommodityPrice().multiply(percentage);
            }else if(Objects.equals(commodity.getRefundServiceChargeType(),ServiceChargeType.FIXED.getCode())){
                return orderCommodity.getCommodityPrice();
            }else {
                throw new BusinessException(SystemError.MALL_MERCHANDISE_23045);
            }
//        }
    }
}
